package cn.zmwh.im.server.modules.ums.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.zmwh.im.common.enums.MessageType;
import cn.zmwh.im.common.pojo.dto.IMUserInfo;
import cn.zmwh.im.server.api.Result;
import cn.zmwh.im.server.constant.IMRedisKey;
import cn.zmwh.im.server.modules.message.pojo.entity.ImMessage;
import cn.zmwh.im.server.modules.message.service.ImMessageService;
import cn.zmwh.im.server.modules.ums.mapper.ImFriendMapper;
import cn.zmwh.im.server.modules.ums.pojo.entity.ImFriend;
import cn.zmwh.im.server.modules.ums.pojo.entity.ImUser;
import cn.zmwh.im.server.modules.ums.pojo.request.Black2ListRequest;
import cn.zmwh.im.server.modules.ums.pojo.request.FriendAddRequest;
import cn.zmwh.im.server.modules.ums.pojo.request.FriendPassRequest;
import cn.zmwh.im.server.modules.ums.pojo.vo.FriendVO;
import cn.zmwh.im.server.netty.MessageService;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 好友 服务实现类
 * </p>
 *
 * @author dmzmwh
 * @since 2025-06-19
 */
@Service
public class ImFriendService extends ServiceImpl<ImFriendMapper, ImFriend> {


    @Autowired
    private ImUserService imUserService;
    @Autowired
    private ImMessageService imMessageService;
    @Autowired
    private MessageService messageService;
    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 获取好友列表
     *
     * @param uid
     * @return
     */
    public Result listByUid(Long uid) {
        List<ImFriend> list = list(Wrappers.<ImFriend>lambdaQuery()
                .eq(ImFriend::getUid, uid)
                .eq(ImFriend::getStatus, 1));
        if (CollUtil.isEmpty(list)) {
            return Result.success();
        }
        Set<Long> ids = list.stream().map(ImFriend::getFriendId).collect(Collectors.toSet());
        List<ImUser> imUsers = imUserService.listByIds(ids);
        HashMap<Long, ImUser> userMapByUid = new HashMap<>();//获取用户信息
        imUsers.forEach(item -> userMapByUid.put(item.getId(), item));

        List<IMUserInfo> userInfos = imUserService.uidToOnline(ids);
        Map<Long, Set<String>> onlineByUid = new HashMap<>();//在线状态
        if (CollUtil.isNotEmpty(userInfos)) {
            for (IMUserInfo userInfo : userInfos) {
                Long id = userInfo.getId();
                String terminal = userInfo.getTerminal();
                onlineByUid.computeIfAbsent(id, k -> new HashSet<>()).add(terminal);
            }
        }

        List<FriendVO> voList = new ArrayList<>();
        for (ImFriend imFriend : list) {
            FriendVO vo = new FriendVO();
            Long friendId = imFriend.getFriendId();
            vo.setFriendId(friendId);
            vo.setCreatedTime(imFriend.getCreatedTime());
            vo.setRemark(imFriend.getRemark());
            ImUser user = userMapByUid.get(friendId);

            vo.setOnline(onlineByUid.get(friendId));
            if (user != null) {
                vo.setNickName(user.getNickName());
                vo.setUserName(user.getUserName());
                vo.setSex(user.getSex());
                vo.setHeadImageThumb(user.getHeadImageThumb());
                vo.setIsBanned(user.getIsBanned());
            }
            voList.add(vo);
        }
        return Result.ok(voList);
    }

    public Result addFriend(FriendAddRequest request) {
        Long friendId = request.getFriendId();
        ImUser byId = imUserService.getById(friendId);
        if (byId == null) {
            throw new RuntimeException("用户不存在");
        }
        Long uid = request.getUid();
        boolean added = false;
        ImFriend addFriend = getOne(Wrappers.<ImFriend>lambdaQuery()
                .eq(ImFriend::getFriendId, uid)
                .eq(ImFriend::getUid, friendId));
        if (addFriend == null) {
            ImFriend friend = new ImFriend();
            friend.setFriendId(request.getUid());
            friend.setUid(friendId);
            friend.setStatus(0);
            friend.setCreatedTime(new Date());
            save(friend);
        } else {
            Integer status = addFriend.getStatus();
            if (status == 1) {
                added = true;//我是对方好友则直接通过
            }
        }


        ImFriend addUid = getOne(Wrappers.<ImFriend>lambdaQuery()
                .eq(ImFriend::getFriendId, friendId)
                .eq(ImFriend::getUid, uid));
        if (addUid == null) {
            ImFriend friend = new ImFriend();
            friend.setUid(request.getUid());
            friend.setFriendId(friendId);
            friend.setStatus(added ? 1 : 0);
            friend.setCreatedTime(new Date());
            save(friend);
        } else {
            Integer status = addUid.getStatus();
            if (status == 1 && added) {
                return Result.success("已添加！");
            }
        }


        String messageId = IdUtil.getSnowflakeNextIdStr();
        ImMessage imMessage = new ImMessage();
        imMessage.setUid(uid);
        imMessage.setSendId(uid);
        imMessage.setRecvId(friendId);
        imMessage.setContent("请求添加好友");
        imMessage.setSendTime(new Date());
        imMessage.setMessageId(messageId);
        imMessage.setType(MessageType.FRIEND_ADD.code());
        if (addFriend != null) {
            return Result.success();
        }
        messageService.messageSendPrivate(imMessage, IMRedisKey.IM_MESSAGE_PRIVATE_QUEUE, friendId, new IMUserInfo(uid, request.getTerminal()), false);
//        Set<Long> ids = Set.of(friendId);
//        List<ImUserInfoDTO> userInfos = imUserService.uidToOnline(ids);
//        Map<String, List<IMUserInfo>> mapByServerId = new HashMap<>();
//        if (CollUtil.isNotEmpty(userInfos)) {
//            userInfos.forEach(dto -> {
//                String serverId = dto.getServerId();
//                mapByServerId.computeIfAbsent(serverId, k -> new ArrayList<>()).add(dto);  // 转型并存入父类 List
//            });
//        }
//
//        List<ImMessage> imList = new ArrayList<>();
//        ImMessage recvImMessage = new ImMessage();
//        BeanUtil.copyProperties(imMessage, recvImMessage);
//        recvImMessage.setUid(friendId);
//        if (CollUtil.isNotEmpty(mapByServerId)) {//好友存在在线终端
//            MessagePrivate messagePrivate = new MessagePrivate();
//            BeanUtil.copyProperties(imMessage, messagePrivate);
//            IMRecvInfo imRecvInfo = new IMRecvInfo();
//            imRecvInfo.setCmd(IMCmdConstants.PRIVATE_MESSAGE);
//            imRecvInfo.setData(messagePrivate);
//            imRecvInfo.setMessageId(messageId);
//            imRecvInfo.setSender(new IMUserInfo(request.getUid(), request.getTerminal()));
//            Set<Map.Entry<String, List<IMUserInfo>>> entries = mapByServerId.entrySet();
//            for (Map.Entry<String, List<IMUserInfo>> entry : entries) {
//                String key = entry.getKey();
//                List<IMUserInfo> value = entry.getValue();
//                imRecvInfo.setReceivers(value);
//                String queueKey = String.join(":", IMRedisKey.IM_MESSAGE_PRIVATE_QUEUE, key);
//                redisTemplate.opsForList().rightPush(queueKey, imRecvInfo);
//            }
//            recvImMessage.setStatus(1);//接收消息是待推送
//            imMessage.setStatus(1);//发送消息是已投递
//        } else {
//            recvImMessage.setStatus(5);//不存在在现在终端，直接等待重连时候推送离线消息
//        }
//        imList.add(imMessage);
//        imList.add(recvImMessage);
//
//
//        try (HintManager hintManager = HintManager.getInstance()) {
//            Set<Long> userIds = imList.stream().map(ImMessage::getUid).collect(Collectors.toSet());
//            Set<MessageDB> messageDBS = imUserService.qryMessageDb(userIds);
//            for (MessageDB messageDB : messageDBS) {
//                Integer messageDb = messageDB.getDb();
//                Integer messageTable = messageDB.getTable();
//                Set<Long> itemUserIds = messageDB.getUserIds();
//                List<ImMessage> itemList = imList.stream().filter(item -> itemUserIds.contains(item.getUid())).collect(Collectors.toList());
//                hintManager.addDbValue(BsKImConstant.DbName.IM_MESSAGE, messageDb);
//                hintManager.addTableValue(messageTable);
//                imMessageService.saveBatch(itemList);
//            }
//        }

        return Result.success();
    }


    @Transactional(rollbackFor = Exception.class)
    public void passFriend(FriendPassRequest request) {
        Long id = request.getId();
        ImFriend imFriend = getById(id);
        Integer status = imFriend.getStatus();
        if (status != 0) {
            throw new RuntimeException("请勿重复操作");
        }
        LambdaUpdateWrapper<ImFriend> wrapper = Wrappers.<ImFriend>lambdaUpdate()
                .set(ImFriend::getStatus, 1);

        LambdaUpdateWrapper<ImFriend> wrapperUid = wrapper.eq(ImFriend::getUid, imFriend.getUid())
                .eq(ImFriend::getFriendId, imFriend.getFriendId());
        this.update(wrapperUid);

        LambdaUpdateWrapper<ImFriend> wrapperFriend = wrapper.eq(ImFriend::getUid, imFriend.getFriendId())
                .eq(ImFriend::getFriendId, imFriend.getUid());
        this.update(wrapperFriend);
    }

    public void delFriend(Long friendId, Long uid) {
        remove(Wrappers.<ImFriend>lambdaQuery()
                .eq(ImFriend::getUid, uid)
                .eq(ImFriend::getFriendId, friendId));

//        单方删除，不删除对方
//        remove(Wrappers.<ImFriend>lambdaUpdate()
//                .eq(ImFriend::getUid, friendId)
//                .eq(ImFriend::getFriendId, uid));

    }

    public void black2list(Black2ListRequest request) {
        //拉黑
        remove(Wrappers.<ImFriend>lambdaUpdate()
                .set(ImFriend::getStatus, 2)
                .eq(ImFriend::getUid, request.getUid())
                .eq(ImFriend::getFriendId, request.getFriendId()));
    }
}
